#!/bin/bash

# 配置参数 数组形式初始化
PROCESS_PATTERNS=("cWosRealtimeDB" "cWosHistoryDB")
OUTPUT_FILE="/var/log/process_monitor.log"
INTERVAL_SECONDS=60
MAX_LOG_SIZE_MB=10

# 创建日志目录
mkdir -p "$(dirname "$OUTPUT_FILE)"

# 检查root权限
# 在 Shell 脚本中，[ 和 ] 周围必须有空格，这是 Shell 语法的硬性要求。这个规则不是可选的风格建议，而是语法必需的
if [ "$(id -u)" -ne 0 ]; then
    echo "[WARN] 建议使用root权限运行此脚本" | tee -a "$OUTPUT_FILE"
fi

# 获取精确时间
get_current_time(){
    # 下面的+指的是自定义输出格式
    date '+%Y-%m-%d %H:%M:%S.%3N' 
}

# 获取进程ID列表
get_process_ids(){
    # 声明局部变量(仅在当前函数作用域有效)
    local pattern=$1
    # 根据名称查找进程ID，pgrep 默认以换行符分隔的进程ID, -d " " 改为空格分隔
    pgrep -d " " "$pattern"
}

# 安全获取进程信息
get_process_info(){
    local pid=$1
    local info=""

    # 检查进程是否存在, dev/null 为空设备；首先将标准输出(stdout) 重定向到 /dev/null（丢弃）；然后将标准错误(stderr) 重定向到当前标准输出的位置（即 /dev/null）
    if ! ps -p "$pid" >/dev/null 2>&1;then
        echo "PID $pid 已退出"
        return 1
    fi

    # 获取内存信息（带错误处理）
    if [ -f "/proc/$pid/status" ];then
        vmsize=$(grep 'VmSize' "/proc/$pid/status" | awk '{print $2}')
        vmrss=$(grep 'VmRSS' "/proc/$pid/status" | awk '{print S2}')
        info+="VmSize=${vmsize:-0}KB VmRSS=${vmrss:-0}KB "
    else
        info+="Vmsize=N/A VmRss=N/A "
    fi

    # 获取文件描述符数
    # 在 Shell 脚本中，$() 和 ${} 是两种完全不同的语法结构，用于不同的目的：
    # $() - 命令替换 (Command Substitution)
    # ${} - 变量扩展 (Variable Expansion)
    if [ -d "/proc/$pid/fd" ];then
        fd_count=$(ls "proc/$pid/fd" 2>dev/null | wc -l)
        info+="FD=${fd_count:-0} "
    else
        info+="FD=N/A "
    fi

    # 获取CPU使用率（瞬时值）
    cpu_usage=$(ps -p "$pid" -o %cpu --no-headers 2>/dev/null |awk '{print $1}')
    info+="CPU=${cpu_usage:-0}%"
    echo "$info"
}

# 主监控循环
while true;do
    {
        echo "=================================="
        echo "监控时间：$(get_current_time)"
        echo "=================================="
    } >> "$OUTPUT_FILE"

    # 遍历进程模式 @表示展开数组PROCESS_PATTERNS的所有元素
    for pattern in "${PROCESS_PATTERNS[@]}";do
        pids=$(get_process_ids "pattern")
        
    done

done